home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / interp / perl5.005.tar.gz / perl5.005.tar / perl5.005 / vms / munchconfig.c < prev    next >
C/C++ Source or Header  |  1998-07-14  |  12KB  |  367 lines

  1. /* munchconfig.c
  2.  
  3.    A very, very (very!) simple program to process a config_h.sh file on
  4.    non-unix systems.
  5.  
  6.    usage:
  7.    munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]] >config.h
  8.  
  9.    which is to say, it takes as its firt parameter a config.sh (or
  10.    equivalent), as its second a config_h.sh (or equvalent), and a list of
  11.    optional tag=value pairs.
  12.  
  13.    It spits the processed config.h out to STDOUT.
  14.  
  15.    */
  16.  
  17. #include <stdio.h>
  18. #include <errno.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22.  
  23. /* The failure code to exit with */
  24. #ifndef EXIT_FAILURE
  25. #ifdef VMS
  26. #define EXIT_FAILURE 0
  27. #else
  28. #define EXIT_FAILURE -1
  29. #endif
  30. #endif
  31.  
  32. /* The biggest line we can read in from a file */
  33. #define LINEBUFFERSIZE 400
  34. #define NUMTILDESUBS 30
  35. #define NUMCONFIGSUBS 1000
  36. #define TOKENBUFFERSIZE 80
  37.  
  38. typedef struct {
  39.   char Tag[TOKENBUFFERSIZE];
  40.   char Value[512];
  41. } Translate;
  42.  
  43. void tilde_sub(char [], Translate [], int);
  44.  
  45. int
  46. main(int argc, char *argv[])
  47. {
  48.   FILE *ConfigSH, *Config_H;
  49.   char LineBuffer[LINEBUFFERSIZE], *TempValue, *StartTilde, *EndTilde;
  50.   char SecondaryLineBuffer[LINEBUFFERSIZE];
  51.   char TokenBuffer[TOKENBUFFERSIZE];
  52.   int LineBufferLength, TempLength, DummyVariable, LineBufferLoop;
  53.   int TokenBufferLoop, ConfigSubLoop, GotIt;
  54.   Translate TildeSub[NUMTILDESUBS];    /* Holds the tilde (~FOO~) */
  55.                                        /* substitutions */
  56.   Translate ConfigSub[NUMCONFIGSUBS];  /* Holds the substitutions from */
  57.                                        /* config.sh */
  58.   int TildeSubCount = 0, ConfigSubCount = 0; /* # of tilde substitutions */
  59.                                              /* and config substitutions, */
  60.                                              /* respectively */
  61.   if (argc < 3) {
  62.     printf("Usage: munchconfig config.sh config_h.sh [foo=bar [baz=xyzzy [...]]]\n");
  63.     exit(EXIT_FAILURE);
  64.   }
  65.  
  66.   
  67.   /* First, open the input files */
  68.   if (NULL == (ConfigSH = fopen(argv[1], "r"))) {
  69.     printf("Error %i trying to open config.sh file %s\n", errno, argv[1]);
  70.     exit(EXIT_FAILURE);
  71.   }
  72.   
  73.   if (NULL == (Config_H = fopen(argv[2], "r"))) {
  74.     printf("Error %i trying to open config_h.sh file %s\n", errno, argv[2]);
  75.     exit(EXIT_FAILURE);
  76.   }
  77.  
  78.   /* Any tag/value pairs on the command line? */
  79.   if (argc > 3) {
  80.     int i;
  81.     char WorkString[80]; 
  82.     for (i=3; i < argc && argv[i]; i++) {
  83.       
  84.       /* Local copy */
  85.       strcpy(WorkString, argv[i]);
  86.       /* Stick a NULL over the = */
  87.       TempValue = strchr(WorkString, '=');
  88.       *TempValue++ = '\0';
  89.  
  90.       /* Copy the tag and value into the holding array */
  91.       strcpy(TildeSub[TildeSubCount].Tag, WorkString);
  92.       strcpy(TildeSub[TildeSubCount].Value, TempValue);
  93.       TildeSubCount++;
  94.     }
  95.   }
  96.  
  97.   /* Now read in the config.sh file. */
  98.   while(fgets(LineBuffer, LINEBUFFERSIZE - 1, ConfigSH)) {
  99.     /* Force a trailing null, just in case */
  100.     LineBuffer[LINEBUFFERSIZE - 1] = '\0';
  101.  
  102.     LineBufferLength = strlen(LineBuffer);
  103.  
  104.     /* Chop trailing control characters */
  105.     while((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] < ' ')) {
  106.       LineBuffer[LineBufferLength - 1] = '\0';
  107.       LineBufferLength--;
  108.     }
  109.  
  110.     /* If it's empty, then try again */
  111.     if (!*LineBuffer)
  112.       continue;
  113.  
  114.     /* If the line begins with a '#' or ' ', skip */
  115.     if ((LineBuffer[0] == ' ') || (LineBuffer[0] == '#'))
  116.       continue;
  117.  
  118.     /* We've got something. Guess we need to actually handle it */
  119.     /* Do the tilde substitution */
  120.     tilde_sub(LineBuffer, TildeSub, TildeSubCount);
  121.  
  122.     /* Stick a NULL over the = */
  123.     TempValue = strchr(LineBuffer, '=');
  124.     *TempValue++ = '\0';
  125.     /* And another over the leading ', which better be there */
  126.     *TempValue++ = '\0';
  127.     
  128.     /* Check to see if there's a trailing ' or ". If not, add a newline to
  129.        the buffer and grab another line. */
  130.     TempLength = strlen(TempValue);
  131.     while ((TempValue[TempLength-1] != '\'') &&
  132.            (TempValue[TempLength-1] != '"'))  {
  133.       fgets(SecondaryLineBuffer, LINEBUFFERSIZE - 1, ConfigSH);
  134.       /* Force a trailing null, just in case */
  135.       SecondaryLineBuffer[LINEBUFFERSIZE - 1] = '\0';
  136.       /* Go substitute */
  137.       tilde_sub(SecondaryLineBuffer, TildeSub, TildeSubCount);
  138.       /* Tack a nweline on the end of our primary buffer */
  139.       strcat(TempValue, "\n");
  140.       /* Concat the new line we just read */
  141.       strcat(TempValue, SecondaryLineBuffer);
  142.  
  143.       /* Refigure the length */
  144.       TempLength = strlen(TempValue);
  145.       
  146.       /* Chop trailing control characters */
  147.       while((TempLength > 0) && (TempValue[TempLength-1] < ' ')) {
  148.         TempValue[TempLength - 1] = '\0';
  149.         TempLength--;
  150.       }
  151.     }
  152.     
  153.     /* And finally one over the trailing ' */
  154.     TempValue[TempLength-1] = '\0';
  155.  
  156.     /* Is there even anything left? */
  157.     if(*TempValue) {
  158.       /* Copy the tag over */
  159.       strcpy(ConfigSub[ConfigSubCount].Tag, LineBuffer);
  160.       /* Copy the value over */
  161.       strcpy(ConfigSub[ConfigSubCount].Value, TempValue);
  162.  
  163.       /* Up the count */
  164.       ConfigSubCount++;
  165.  
  166.     }
  167.   }
  168.  
  169.   /* Okay, we've read in all the substititions from our config.sh */
  170.   /* equivalent. Read in the config_h.sh equiv and start the substitution */
  171.   
  172.   /* First, eat all the lines until we get to one with !GROK!THIS! in it */
  173.   while(!strstr(fgets(LineBuffer, LINEBUFFERSIZE, Config_H),
  174.                 "!GROK!THIS!")) {
  175.  
  176.     /* Dummy statement to shut up any compiler that'll whine about an empty */
  177.     /* loop */
  178.     DummyVariable++;
  179.   }
  180.  
  181.   /* Right, we've read all the lines through the first one with !GROK!THIS! */
  182.   /* in it. That gets us through the beginning stuff. Now start in earnest */
  183.   /* with our translations, which run until we get to another !GROK!THIS! */
  184.   while(!strstr(fgets(LineBuffer, LINEBUFFERSIZE, Config_H),
  185.                 "!GROK!THIS!")) {
  186.     /* Force a trailing null, just in case */
  187.     LineBuffer[LINEBUFFERSIZE - 1] = '\0';
  188.     
  189.     /* Tilde Substitute */
  190.     tilde_sub(LineBuffer, TildeSub, TildeSubCount);
  191.  
  192.     LineBufferLength = strlen(LineBuffer);
  193.     
  194.     /* Chop trailing control characters */
  195.     while((LineBufferLength > 0) && (LineBuffer[LineBufferLength-1] < ' ')) {
  196.       LineBuffer[LineBufferLength - 1] = '\0';
  197.       LineBufferLength--;
  198.     }
  199.  
  200.     /* Right. Go looking for $s. */
  201.     for(LineBufferLoop = 0; LineBufferLoop < LineBufferLength;
  202.         LineBufferLoop++) {
  203.       /* Did we find one? */
  204.       if ('$' != LineBuffer[LineBufferLoop]) {
  205.         /* Nope, spit out the value */
  206.         putchar(LineBuffer[LineBufferLoop]);
  207.       } else {
  208.         /* Yes, we did. Is it escaped? */
  209.         if ((LineBufferLoop > 0) && ('\\' == LineBuffer[LineBufferLoop -
  210.                                                        1])) {
  211.           /* Yup. Spit it out */
  212.           putchar(LineBuffer[LineBufferLoop]);
  213.         } else {
  214.          /* Nope. Go grab us a token */
  215.           TokenBufferLoop = 0;
  216.           /* Advance to the next character in the input stream */
  217.           LineBufferLoop++;
  218.           while((LineBufferLoop < LineBufferLength) &&
  219.                 ((isalnum(LineBuffer[LineBufferLoop]) || ('_' ==
  220.                                                           LineBuffer[LineBufferLoop])))) {
  221.             TokenBuffer[TokenBufferLoop] = LineBuffer[LineBufferLoop];
  222.             LineBufferLoop++;
  223.             TokenBufferLoop++;
  224.           }
  225.  
  226.           /* Trailing null on the token buffer */
  227.           TokenBuffer[TokenBufferLoop] = '\0';
  228.  
  229.           /* Back the line buffer pointer up one */
  230.           LineBufferLoop--;
  231.           
  232.           /* Right, we're done grabbing a token. Check to make sure we got */
  233.           /* something */
  234.           if (TokenBufferLoop) {
  235.             /* Well, we do. Run through all the tokens we've got in the */
  236.             /* ConfigSub array and see if any match */
  237.             GotIt = 0;
  238.             for(ConfigSubLoop = 0; ConfigSubLoop < ConfigSubCount;
  239.                 ConfigSubLoop++) {
  240.               if (!strcmp(TokenBuffer, ConfigSub[ConfigSubLoop].Tag)) {
  241.                 GotIt = 1;
  242.                 printf("%s", ConfigSub[ConfigSubLoop].Value);
  243.                 break;
  244.               }
  245.             }
  246.  
  247.             /* Did we find something? If not, spit out what was in our */
  248.             /* buffer */
  249.             if (!GotIt) {
  250.               printf("$%s", TokenBuffer);
  251.             }
  252.             
  253.           } else {
  254.             /* Just a bare $. Spit it out */
  255.             putchar('$');
  256.           }       
  257.         }
  258.       }
  259.     }
  260.     
  261.     /* We're all done. Spit out an EOL */
  262.     printf("\n");
  263.     
  264.     
  265.   }
  266.   
  267.   /* Close the files */
  268.   fclose(ConfigSH);
  269.   fclose(Config_H);
  270. }
  271.  
  272. void
  273. tilde_sub(char LineBuffer[], Translate TildeSub[], int TildeSubCount)
  274. {
  275.   char TempBuffer[LINEBUFFERSIZE], TempTilde[TOKENBUFFERSIZE];
  276.   int TildeLoop, InTilde, CopiedBufferLength, TildeBufferLength, k, GotIt;
  277.   int TempLength;
  278.   InTilde = 0;
  279.   CopiedBufferLength = 0;
  280.   TildeBufferLength = 0;
  281.   TempLength = strlen(LineBuffer);
  282.  
  283.   /* Grovel over our input looking for ~foo~ constructs */
  284.   for(TildeLoop = 0; TildeLoop < TempLength; TildeLoop++) {
  285.     /* Are we in a tilde? */
  286.     if (InTilde) {
  287.       /* Yup. Is the current character a tilde? */
  288.       if (LineBuffer[TildeLoop] == '~') {
  289.         /* Yup. That means we're ready to do a substitution */
  290.         InTilde = 0;
  291.         GotIt = 0;
  292.         /* Trailing null */
  293.         TempTilde[TildeBufferLength] = '\0';
  294.         for( k=0; k < TildeSubCount; k++) {
  295.           if (!strcmp(TildeSub[k].Tag, TempTilde)) {
  296.             GotIt = 1;
  297.             /* Tack on the trailing null to the main buffer */
  298.             TempBuffer[CopiedBufferLength] = '\0';
  299.             /* Copy the tilde substitution over */
  300.             strcat(TempBuffer, TildeSub[k].Value);
  301.             CopiedBufferLength = strlen(TempBuffer);
  302.           }
  303.         }
  304.         
  305.         /* Did we find anything? */
  306.         if (GotIt == 0) {
  307.           /* Guess not. Copy the whole thing out verbatim */
  308.           TempBuffer[CopiedBufferLength] = '\0';
  309.           TempBuffer[CopiedBufferLength++] = '~';
  310.           TempBuffer[CopiedBufferLength] = '\0';
  311.           strcat(TempBuffer, TempTilde);
  312.           strcat(TempBuffer, "~");
  313.           CopiedBufferLength = strlen(TempBuffer);
  314.         }
  315.         
  316.       } else {
  317.         /* 'Kay, not a tilde. Is it a word character? */
  318.         if (isalnum(LineBuffer[TildeLoop]) || (LineBuffer[TildeLoop] =
  319.                                               '-') ||
  320.             (LineBuffer[TildeLoop] == '-')) {
  321.           TempTilde[TildeBufferLength++] = LineBuffer[TildeLoop];
  322.         } else {
  323.           /* No, it's not a tilde character. For shame! We've got a */
  324.           /* bogus token. Copy a ~ into the output buffer, then append */
  325.           /* whatever we've got in our token buffer */
  326.           TempBuffer[CopiedBufferLength++] = '~';
  327.           TempBuffer[CopiedBufferLength] = '\0';
  328.           TempTilde[TildeBufferLength] = '\0';
  329.           strcat(TempBuffer, TempTilde);
  330.           CopiedBufferLength += TildeBufferLength;
  331.           InTilde = 0;
  332.         }
  333.       }
  334.     } else {
  335.       /* We're not in a tilde. Do we want to be? */
  336.       if (LineBuffer[TildeLoop] == '~') {
  337.         /* Guess so */
  338.         InTilde = 1;
  339.         TildeBufferLength = 0;
  340.       } else {
  341.         /* Nope. Copy the character to the output buffer */
  342.         TempBuffer[CopiedBufferLength++] = LineBuffer[TildeLoop];
  343.       }
  344.     }
  345.   }
  346.   
  347.   /* Out of the loop. First, double-check to see if there was anything */
  348.   /* pending. */
  349.   if (InTilde) {
  350.     /* bogus token. Copy a ~ into the output buffer, then append */
  351.     /* whatever we've got in our token buffer */
  352.     TempBuffer[CopiedBufferLength++] = '~';
  353.     TempBuffer[CopiedBufferLength] = '\0';
  354.     TempTilde[TildeBufferLength] = '\0';
  355.     strcat(TempBuffer, TempTilde);
  356.     CopiedBufferLength += TildeBufferLength;
  357.   } else {
  358.     /* Nope, nothing pensing. Tack on a \0 */
  359.     TempBuffer[CopiedBufferLength] = '\0';
  360.   }
  361.  
  362.   /* Okay, we're done. Copy the temp buffer back into the line buffer */
  363.   strcpy(LineBuffer, TempBuffer);
  364.  
  365. }
  366.  
  367.